{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# K-Nearest Neighbors\n",
    "<p>KNN is a form of <i>instance</i>, or <i>memory</i> based learning wherein we don't learn a function $f(X)$ to estimate $E[Y|X]$. Rather, to make a classification for a given instance $X_i$, we search the training data for the $k$ nearest neighbors, as defined by some distance metric $d(X_i,X_j)$. The estimate of $E[Y|X]$ is then given by:<br><br>\n",
    "\n",
    "<center>$E[Y|X] = \\sum\\limits_{y_i \\in N(X)}^k Y_i$</center><br><br>\n",
    "\n",
    "The most common distance function used in kNN is the <i>Euclidean Distance</i>.<br><br>\n",
    "\n",
    "Let $X = <x^1,...x^p>$ be a $p$-dimensional vector, then for two instances $i$ and $j$:<br><br>\n",
    "<center>$eud(X_i,X_j) = \\sqrt{(x_i^1-x_j^1)^2+...+(x_i^p-x_j^p)^2} = \\sqrt{\\sum\\limits_{t=1}^p (x_i^t-x_j^t)^2}$\n",
    "</center>\n",
    "<br><br>\n",
    "In the following example we run kNN on some real data from an ad conversion prediction dataset.\n",
    "</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "'''\n",
    "This block loads the data, downsamples it, splits to train/test and rescales it.\n",
    "'''\n",
    "\n",
    "import pandas as pd\n",
    "import sys\n",
    "#sys.path.append(\"C:/Users/kevin/Documents/GitHub/DS_course/ipython\")\n",
    "\n",
    "#Get the datadir path set up - note this may only work in Linux/MAC\n",
    "import os\n",
    "cwd = os.getcwd()\n",
    "datadir = '/'.join(cwd.split('/')[0:-1]) + '/data/'\n",
    "#If it doesn't work, hard code the datadir\n",
    "#datadir = ${path}\n",
    "\n",
    "\n",
    "import numpy as np\n",
    "import course_utils as bd\n",
    "import imp\n",
    "imp.reload(bd)\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "#KNN is implemented as a class in sklearn.neighbors\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "#Load data and downsample for a 50/50 split, then split into a train/test\n",
    "f = datadir + 'ads_dataset_cut.txt'\n",
    "\n",
    "train_split = 0.5\n",
    "\n",
    "tdat = pd.read_csv(f, header = 0, sep = '\\t')\n",
    "moddat = bd.evenSplit(tdat,'y_buy')\n",
    "#Randomly sort moddat\n",
    "moddat['sort']=np.random.random(moddat.shape[0])\n",
    "moddat = moddat.sort_values(by='sort')\n",
    "moddat = moddat.drop('sort', axis=1)\n",
    "\n",
    "moddat_scale =bd.scaleData(moddat)\n",
    "\n",
    "\n",
    "#We know the dataset is sorted so we can just split by index\n",
    "train = moddat[:int(np.floor(moddat.shape[0] * train_split))]\n",
    "test = moddat[int(np.floor(moddat.shape[0] * train_split)):]\n",
    "\n",
    "#Scale the data to [0,1] interval...note that scaleData doesn't rescale by variance\n",
    "train_scale = moddat_scale[:int(np.floor(moddat_scale.shape[0] * train_split))]\n",
    "test_scale = moddat_scale[int(np.floor(moddat_scale.shape[0] * train_split)):]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "\n",
    "def testKnn(k, train, test, lab, p = 2):\n",
    "    '''\n",
    "    Run kNN classification and return accuracy \n",
    "    '''\n",
    "    X_train = train.drop(lab, 1)\n",
    "    y_train = train[lab]\n",
    "    #Specify k and use p=2 for Euclidean distance\n",
    "    neigh = KNeighborsClassifier(n_neighbors = k, p = p)\n",
    "    #doesn't really fit the model in a classic sense, it does some intelligent partitioning of the data\n",
    "    neigh.fit(X_train, y_train)\n",
    "    #Get the predictions...note, this returns a class label prediction, not a probability\n",
    "    cm = confusion_matrix(test[lab], neigh.predict(test.drop(lab, 1)))\n",
    "    return (cm[0][0] + cm[1][1]) / float(np.sum(cm))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p>Given a feature set and a distance function, the paramater that controls complexity is the number of neighbors used $k$. Like with all complexity parameters, the optimal value is dependent on the data, and is generally the one that exploits the best bias-variance tradeoff. <br><br>\n",
    "\n",
    "The following is an example grid search to find the optimal $k$. We also create 2 other variants of the data to show the effect of each on accuracy.<br>\n",
    "\n",
    "<ul>\n",
    "    <li>The training set size</li>\n",
    "    <li>The scaling of the features</li>\n",
    "</ul><br>\n",
    "\n",
    "Note that Euclidean distance is not scale invariant. Features with higher norms will in general dominate the neighborhood. If the features with the highest norms are also not that predictive, then the model predictions suffer. It is often best to rescale the features before running kNN.\n",
    "\n",
    "\n",
    "</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nsZqYl5iYyKhRo5g4cSIACQkJ3HLLLZU2EjaqapYvX87ixYvx8fGhSZMmvPbll4QIwdTnnuPu3r3x\natiQ22+/nYULFzJz5kwef/xxgoOD6d+/P4cOHbrkeh988AGjRo0iOjoak8lE3759+eSTT0hISGDw\n4MHceuut9OrVi1atWoGUVJw6xYGcHELMcxTMBATw1PTpnCosRHp7ExMTwyeffALAfffdx7p162jf\nvj0NGzZ0qmrJHl26dCEyMpKOHTvSunVrevfu7fikoiIlGM2aOa5U8vJizKhRDBk5kshOnYi89VYi\nIyMJNPfcqg1sDxo0iAZGVVx4eDjf/O//8sKkSfx7xQqaN2/OnDlzGDp0KJs2bWLWrFl0796dxo0b\nc8cdd1z2jOnAwEC2bdtGQkICTZs2ZdmyZVVe9/PzY+XKlYwdO5Zz585RXl7Oyy+/TPv27XnyyScp\nLCykoqKCSZMmEXCNWpNoPJPr2kgwKyuLTp06Xf1gTp5Ulh3R0bZ/5UoJv/6qUh2tWjl/3bNn1bKu\n/v4QEVGzoeGVcv48v61Zwxdbt/KuIQRV2L9fCaEzHllXi4oK5d7r4wMdOzpV1moqKsK0ezf127Yl\nu7iY2NhYsletwrtBA3WNmjh1Cv77X7VAVsOGdfQhVK8iNDSUfKNE2RW47Tuh8Vi0kaA7sS6ftSUW\nZWXqBufMJD9rgoPVgkwHD6qBVlcIxunT3BYRwbvV5lFYCApSQlhSouaIeAJnzqg2bdXK6fkPRSYT\n94wYgeniRaSfH/989128y8svLZe1RVCQEguzuaRGcwOgxcIVOJprYcvmw1lCQlTP5NAhNUmsffu6\nE4yKCnXjDQqyn7M3l9AWFDgnFhUVKs6QEOdt2y+Higo10a5hw8rYnCAoKIid//d/SnTbtlWf+/x5\n59x+fXxUae6ZM86lvZzE29vbpb0KjaY2uHuexfWJs2Jxpb/MGzVSN7jCQpWWqiuH2nPn1CCveW6F\nLfz8Ks0VneGPP9R1jxxxzWpzJ05UWpJc7k375pvV58nNVeLXuLHz610EB6v3vZb8sjSaWqDFwhV4\neambjr2b44ULSlDs/Xp3hkaNlPX2uXPql3tdlEnm5amYHNmLBAWpAWVH71laqm7EAQGqN3TsWO1j\ntKasTF0/KOiyehUWhFBpp5KSmstlbWHugThjW37xoudYzms0V4gWC1dgNTHPJhcuXFkKqjqhoZWC\nsXu3Gss4e/bKbkwmk+othIQ4/nUdGKhu/gUFNR939Khqi7Zt1aJDeXlKZOqKY8cqFyW6Uho1Up83\nONhxya01Pj5KBGsSCylVzyo9Hfburd064BqNm9Fi4SrsiUVFhfolWxdiAUowOnZUN/lz51Raavdu\nNaaRn++8cJw5o25uNaWgzPj7q95TTWJx7px6/6ZNK40RfXxUOqouKvAKC1XMTZpc6tp7OXh7q6qm\n1q0v/9zgYPW3tJWKKilR66kfO6ba68IFNT6iBUNzjaLFwlX4+nL40KFLLcqnT+edxMS6EwtQN6M2\nbVSpbkQEBAezMDGR0S+8UCkcBQU1C0deHm0GDuS0g4lc/fr1o0PHjsQ89RQx8fGsXLHi0oMqKpQo\n+Pnx7JQprFy5Ery86DdqFKmpqWo2usHDDz9MTEwM7du3JzAw0GJbvn37dvtBSKmu7+sLTZrw0Ucf\nscSYYGePn3/+mQkTJth+sX79yyoSyMrK4u677ybm3nvp9PjjvDRiRNXYTp6EPXuUQLRty0Fvb5am\npakB9OzsukkZajRXGV0N5Sp8fW3/ijTvq0uxMFOvnkoRBQaq1ExOjsqt5+dXjkcEBaleiLUlRkmJ\ncpS1M0mwOkuWLKFb27ZKhGzNSTh5Ul2zffuq1/P2VlVLOTmWxYhWr14NwNatW3nnnXdYu3atzfc0\nmUx4m8d4Tp1SN+JbbgEvL0aNGuUw5h49etCjRw+HxznD6NGjeeWVV7j//vuRWVn8tneveqG0FA4f\nVr2em29WAu7ry8Fff2Xpd9/xxCOPuLbsWaNxITeMWIwfD2YH6roiJqYGf0Jz/rt6ysU86F2/Pv36\n9aNHjx5s2bKF/Px8FixYwF133UVmZibPPfccZWVlVFRU8PXXXxMREUFiYiLvvPMOQgiio6NZvHgx\n3333HW+++SZlhhfVkiVLCA8PVzd+X19o25ZTJ07w4vPPc+TwYSgv572JE+ndtSt5wOCJE8nJyaFn\np05IZyuBoEoJ7eHTp3nggQeUc2pZGe/Mnk1ReTkzrSxGLDRpogQzJ8dh6qdFixY8/fTTJCUl8dpr\nr5GXl8eCzz+n7Nw5/tSuHYmrVtEAmDZtGqGhoYwfP54+ffrQp08fNm/eTEFBAf/617/o1asXycnJ\nzJs3j2+++YZp06aRm5vLgQMHOHr0KC+//LJFcBISEli6dClhYWE0a9aMnj17Mr6aFX1ubq7FvE+E\n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\nTkSuQmCC\n",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "go=1\n",
    "if (go==1):\n",
    "    s1=[ testKnn(i, train[:50], test,'y_buy', p = 2) for i in range(1, 40) ]\n",
    "    s2=[ testKnn(i, train, test, 'y_buy', p = 2) for i in range(1, 40) ]\n",
    "    s3=[ testKnn(i, train_scale, test_scale, 'y_buy', p = 2) for i in range(1, 40) ]\n",
    "    \n",
    "x = range(1, 40)\n",
    "    \n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "p1 = plt.plot(x,s1,'r-', label = 'Unscaled, 50 Training Examples')\n",
    "p2 = plt.plot(x,s2,'b-', label = 'Unscaled, Full Training Set')\n",
    "p3 = plt.plot(x,s3,'g-', label = 'Scaled, Full Training Set')\n",
    "plt.title('Accuracy of kNN with varied k and other options')\n",
    "plt.legend(loc = 3)\n",
    "ax.set_xlabel('k')\n",
    "ax.set_ylabel('Test Set Accuracy')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p>One major challenge with kNN is that the expected distance between any two points in $p$-dimensional space increases as $p$ increases. The following is a simulation that illustrates this concept.<br><br>\n",
    "\n",
    "We generate $n$ uniformly distributed samples in a $p$-dimensional hyper-cube. We then show the average distance between instances increases as we consider more dimensions.\n",
    "\n",
    "</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "No handles with labels found to put in legend.\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "'''\n",
    "Show curse of dimensionality\n",
    "'''\n",
    "import numpy as np\n",
    "\n",
    "#Generate a random matrix in a uniform hyper-cube\n",
    "\n",
    "n = 100\n",
    "d = 50\n",
    "X = np.random.rand(n, d)\n",
    "\n",
    "dims = range(2, d)\n",
    "dists = dict()\n",
    "\n",
    "go = 1\n",
    "if (go==1):\n",
    "    for dim in dims:\n",
    "        dists[dim] = list()\n",
    "\n",
    "    #Now get all pairwise distances of various dimensions\n",
    "    for i in range(n):\n",
    "        for j in range(i + 1, n):\n",
    "            for dim in dims:\n",
    "                dists[dim].append(np.sqrt((sum((X[i, :dim] - X[j, :dim])**2))))\n",
    "\n",
    "    means=[ np.array(dists[dim]).mean() for dim in dims ]\n",
    "\n",
    "\n",
    "    \n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "plt.plot(dims,means)\n",
    "plt.title('Avg Pairwise Distance in Unit Hypercube by Dimension')\n",
    "plt.legend(loc=3)\n",
    "ax.set_xlabel('Dimension of Cube')\n",
    "ax.set_ylabel('Avg Pairwise Distance')\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p>Now we plot this histogram of distances, and not just the mean distance by dimension $p$.</p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/briand/anaconda/envs/py35/lib/python3.5/site-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance.  In a future version, a new instance will always be created and returned.  Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.\n",
      "  warnings.warn(message, mplDeprecation, stacklevel=1)\n",
      "/Users/briand/anaconda/envs/py35/lib/python3.5/site-packages/matplotlib/axes/_axes.py:6571: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.\n",
      "  warnings.warn(\"The 'normed' kwarg is deprecated, and has been \"\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "'''\n",
    "Plot histogram of pairwise distances\n",
    "'''\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "r = (0,12)\n",
    "b = 24\n",
    "fig = plt.figure()\n",
    "frame = plt.gca()\n",
    "ax = fig.add_subplot(111)\n",
    "h1 = plt.hist(dists[2], range=r, bins=b, normed=True, histtype='step',stacked=True,label='Dim=2')\n",
    "h2 = plt.hist(dists[10],range=r, bins=b, normed=True, histtype='step',stacked=True,label='Dim=10')\n",
    "h3 = plt.hist(dists[20],range=r, bins=b, normed=True, histtype='step',stacked=True,label='Dim=30')\n",
    "h4 = plt.hist(dists[40],range=r, bins=b, normed=True, histtype='step',stacked=True,label='Dim=40')\n",
    "frame.axes.get_yaxis().set_ticks([])\n",
    "ax.set_xlabel('Pairwise Distance')\n",
    "ax.set_ylabel('Pct of Pairs with Distance')\n",
    "plt.title('Histogram of Pairwise Distances by Dimensionality of X')\n",
    "plt.legend()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [py35]",
   "language": "python",
   "name": "Python [py35]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
